import { handleResult } from './handler'
import { resToObject } from './utils'

export function benchmark(functions, { args = [], style = 'percent', sample = 50, frequency = 500000 } = {}) {
  if (!functions) throw new Error('az-benchmark: Expect functions but missing.')

  const isFunctionList = Array.isArray(functions)
  const fList = isFunctionList ? functions : Object.values(functions)

  const results = []

  const bench = createBench(frequency)

  for (let f of fList) {
    bench(f, ...args)
  }

  for (let i = 0; i < sample; i++) {
    for (let index in fList) {
      results[index]
        ? results[index].push(bench(fList[index], ...args))
        : (results[index] = [bench(fList[index], ...args)])
    }
  }

  const res = handleResult(results, style, frequency) || benchmark(...arguments)

  return isFunctionList ? res : resToObject(res, Object.keys(functions))
}

function createBench(frequency) {
  return function (f, ...args) {
    const start = Date.now()
    for (let i = 0; i < frequency; i++) f(...args)
    return Date.now() - start
  }
}
